//
// Created by nvidia on 2021/4/28.
//

#ifndef ALLIANCE_SENTRY_V2_0_SERIAL_H
#define ALLIANCE_SENTRY_V2_0_SERIAL_H
#ifdef Windows

#include <Windows.h>

#elif defined(Linux)

#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <unistd.h>
#include "additions.h"
#include <iostream>

struct Txpackage                     //float 4字节 char 1字节 short 2字节 4int 4字节
{
public:
    char send_message1[1000],send_message2[1000];
    unsigned char t_buf[10];
    Txpackage()=default;
    Txpackage operator() (const cv::Point3f &pyz, const int &id,const int &armor_size_tag,const int &shoot_flag);
    ~Txpackage()=default;
};

struct Rxpackage
{
    union {
        short type_short=0;
        char type_2char[2];
    } pitch_angle,pitch_speed,yaw_speed,chassis_location,chassis_speed,chassis_acceleration;//都是电控取了小数点后两位以后×100发过来的
    union{
        int32_t type_int=0;
        char type_2char[4];
    }yaw_angle;
    float   bullet_spd=25;
    short int   shakemode_outpostalive_mycolor_findtarget=-1;
    bool bfind_target;
    int enemy_color;
    bool outpost_alive=true,shake_mode=false;
    char enemy_alive_flag=0xff,enemy_blood=0x00;
    // 0:0000 底盘向左移动，己方为红方，已找到敌人；
    // 1:0001 底盘向左移动，己方为红方，未找到敌人；
    // 2:0010 底盘向左移动，己方为蓝方，已找到敌人；
    // 3:0011 底盘向左移动，己方为蓝方，未找到敌人；
    // 4:0100 底盘不移动，己方为红方，已找到敌人；
    // 5:0101 底盘不移动，己方为红方，未找到敌人；
    // 6:0110 底盘不移动，己方为蓝方，已找到敌人；
    // 7:0111 底盘不移动，己方为蓝方，未找到敌人；
    // 8:1000 底盘向右移动，己方为红方，已找到敌人；
    // 9:1001 底盘向右移动，己方为红方，未找到敌人；
    // 10:1010 底盘向右移动，己方为蓝方，已找到敌人；
    // 11:1011 底盘向右移动，己方为蓝方，未找到敌人；
    short int   another_shoot_id=-1;
    char read_message1[1000],read_message2[1000],read_message3[1000],read_message4[1000];
    bool success_flag=false;
    Rxpackage()= default;
    ~Rxpackage()=default;
};

#define SERIAL_ROUND_VOLUME 150
class Serial {
private:
    int fd;
    int nSpeed;
    char nEvent;
    int nBits;
    int nStop;

    int set_opt(int fd, int nSpeed, char nEvent, int nBits, int nStop);

public:
    Rxpackage rxpackage;
    Txpackage txpackage;
    RoundQueue<float,3> qPitches,qYaws,qP_speeds,qY_speeds;
    RoundQueue<float,3> qChassis_locations,qChss_spd;
    RoundQueue<float,3> qChss_acc;
    systime t=0,last_t=0;

    Serial()=default;
    Serial(int nSpeed = 115200, char nEvent = 'N', int nBits = 8, int nStop = 1);
    ~Serial();

    void setFCNTL(){
        fcntl(fd,F_SETFL,FNDELAY);
    }

    bool InitPort(int nSpeed = 115200, char  nEvent = 'N', int nBits = 8, int nStop = 1);
    bool WriteData(const unsigned char* pData, unsigned int length);
    bool ReadData(unsigned char* buffer, unsigned int length);
    friend bool readTarget(Serial &serial);
};

bool sendTarget(Serial &serial,Txpackage txpackage);
void showSerial(const cv::Mat& src,Txpackage txpackage,Rxpackage rxpackage);

#endif
#endif //ALLIANCE_SENTRY_V2_0_SERIAL_H
